/*
 *  author: lichuang
 *  2010-09-27
 */

#include <assert.h>
#include "stack.h"
#include "common/common.h"
#include "common/array.h"

stack_t* stack_create(int size) {
  stack_t *stack = (stack_t*)malloc(sizeof(stack_t));
  assert(stack != NULL);
  stack->array = array_create(size);
  stack->size = 0;
  return stack;
}

stack_t* stack_resize(stack_t *stack, int new_size) {
  assert(stack != NULL);
  stack->array = array_resize(stack->array, new_size);
  int size = new_size > stack->size ? stack->size : new_size;
  stack->size = size;
  return stack;
}

void stack_destroy(stack_t *stack) {
  assert(stack != NULL);
  array_destroy(stack->array);
  free(stack);
}

void stack_init(stack_t *stack) {
  assert(stack != NULL);
  array_init(stack->array);
  stack->size = stack->array->size;
}

void stack_print(const stack_t *stack, const char *msg) {
  if (msg != NULL) {
    printf("%s\n", msg);
  } else {
    printf("\n");
  }
  printf("size of the stack: %d\n", stack->size);
  printf("elements of the stack:\n");
  int i, size;
  const int *p = stack->array->data;
  for (i = 0, size = stack->size; i < size; ++i) {
    printf("%d ", p[i]);
  }
  printf("\n");
}

int  stack_empty(struct stack_t *stack) {
  assert(stack != NULL);
  assert(stack->array != NULL);
  assert(stack->size >= 0);
  if (stack->size > 0) {
    return 0;
  } else {
    return 1;
  }
}

void stack_push(struct stack_t *stack, int value) {
  assert(stack != NULL);
  assert(stack->array != NULL);
  assert(stack->size >= 0);
  if (stack->size == stack->array->size) {
    stack->array = array_resize(stack->array,
                                stack->size + DEFAULT_ARRAY_SIZE);
  }
  stack->array->data[stack->size++] = value;
}

int  stack_pop(struct stack_t *stack) {
  assert(stack != NULL);
  assert(stack->array != NULL);
  assert(stack->size >= 0);
  int value = stack->array->data[--stack->size];
  return value;
}

